package com.czk.rdd.operator.transform

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

/**
 * @Author:ChenZhangKun
 * @Date: 2021/12/9 16:32
 */
object GroupByKey {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)

    val rdd = sc.makeRDD(List(("a", 1), ("a", 2), ("b", 3), ("a", 4)))
    // 将数据源的数据根据 key 对 value 进行分组
    // 第一个元素的相同的key，第二个是相同key的value集合
    // reduceByKey 和 groupByKey 都存在 shuffle 的操作，但是 reduceByKey
    // 可以在 shuffle 前对分区内相同 key 的数据进行预聚合（combine）功能，这样会减少落盘的
    // 数据量，而 groupByKey 只是进行分组，不存在数据量减少的问题，reduceByKey 性能比较高

    // reduceByKey 其实包含分组和聚合的功能。GroupByKey 只能分组，不能聚
    // 合，所以在分组聚合的场合下，推荐使用 reduceByKey，如果仅仅是分组而不需要聚合。那
    // 么还是只能使用 groupByKey
    val rdd1: RDD[(String, Iterable[Int])] = rdd.groupByKey()

    rdd1.collect().foreach(println)
  }
}
